<template>
  <Dialog v-model="dialogVisible" :title="dialogTitle" width="1200px">
    <div class="formTitle">用例基本信息</div>
    <el-form ref="formRef" v-loading="formLoading" :model="formData" :rules="formRules" label-width="90px">
      <el-row>
        <el-col :span="12">
          <el-form-item label="名称" prop="name">
            <el-input v-model="formData.name" placeholder="请输入名称" :disabled="formType === 'view'" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="标识" prop="logo">
            <el-input v-model="formData.logo" disabled />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="提测单" prop="requestFormId">
            <el-select v-model="formData.requestFormId" placeholder="请选择提测单" :disabled="formType === 'view'"
              @change="requestFormidChange">
              <el-option v-for="item in testformList" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="需求" prop="functionList">
            <el-cascader v-model="formData.functionList" :options="demandList" :props="defaultProps" placeholder="请选择需求"
              style="width: 100%" :disabled="formType === 'view'" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="12">
          <el-form-item label="用例集" prop="suite">
            <el-cascader v-model="formData.suite" :options="testboxList" :props="defaultProps" placeholder="请选择用例集"
              style="width: 100%" :disabled="formType === 'view'" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="类型" prop="type">
            <el-select v-model="formData.type" placeholder="请选择类型" :disabled="formType === 'view'">
              <el-option v-for="item in getIntDictOptions(DICT_TYPE.TEST_TYPE)" :key="item.value" :label="item.label"
                :value="item.value" />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-form-item label="综述" prop="review">
            <el-input v-model="formData.review" placeholder="请输入综述" type="textarea" :disabled="formType === 'view'" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-form-item label="初始化条件" prop="initialize">
            <el-input v-model="formData.initialize" placeholder="请输入初始化条件" type="textarea"
              :disabled="formType === 'view'" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-form-item label="测试方法" prop="method">
            <el-input v-model="formData.method" placeholder="请输入测试方法" type="textarea" :disabled="formType === 'view'" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-form-item label="通过准则" prop="passCondition">
            <el-input v-model="formData.passCondition" placeholder="请输入通过准则" type="textarea"
              :disabled="formType === 'view'" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-form-item label="终止条件" prop="stopCondition">
            <el-input v-model="formData.stopCondition" placeholder="请输入终止条件" type="textarea"
              :disabled="formType === 'view'" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <div class="formTitle">用例步骤</div>
    <el-table :data="formData.testCaseStepsDO">
      <el-table-column prop="number" label="序号" min-width="5%" />
      <el-table-column prop="operation" label="用例具体操作" min-width="30%">
        <template #default="scope">
          <el-input v-model="scope.row.operation" :value="scope.row.operation" placeholder="请输入用例具体操作" type="textarea"
            :autosize="{ minRows: 2 }" :disabled="formType === 'view'" />
        </template>
      </el-table-column>
      <el-table-column prop="expect" label="期望结果" min-width="30%">
        <template #default="scope">
          <el-input v-model="scope.row.expect" :value="scope.row.expect" placeholder="请输入期望结果" type="textarea"
            :autosize="{ minRows: 2 }" :disabled="formType === 'view'" />
        </template>
      </el-table-column>
      <el-table-column label="操作" align="left" min-width="15%" v-if="formType !== 'view'">
        <template #default="scope">
          <el-tooltip class="item" effect="dark" content="添加" placement="top">
            <el-button :icon="Plus" circle @click="handleAdd(scope.$index, scope.row)" />
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="删除" placement="top">
            <el-button :icon="Delete" circle @click="handleDel(scope.$index, scope.row)" />
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="向上移位" placement="top">
            <el-button :icon="Top" circle @click="handleUp(scope.$index, scope.row)" v-show="scope.row.number > 1" />
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="向下移位" placement="top">
            <el-button :icon="Bottom" circle @click="handleDown(scope.$index, scope.row)"
              v-show="scope.$index < formData.testCaseStepsDO.length - 1" />
          </el-tooltip>
        </template>
      </el-table-column>
    </el-table>
    <template #footer>
      <el-button :disabled="formLoading" v-if="formType !== 'view'" type="primary" @click="submitForm">确 定</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
</template>
<script lang="ts" setup>
import * as UseCaseApi from '@/api/usecase'
import { FormRules } from 'element-plus'
import { Plus, Delete, Top, Bottom } from '@element-plus/icons-vue'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'

defineOptions({ name: 'UseCaseForm' })

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

let projectId = ref()
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const formType = ref('') // 表单的类型：create - 新增；update - 修改
const formData = ref({
  name: '',
  logo: '',
  type: '',
  requestFormId: '',
  functionList: '',
  suite: '',
  review: '',
  initialize: '',
  method: '',
  passCondition: '',
  stopCondition: '',
  testCaseStepsDO: [
    { id: 0, number: 1, operation: "", expect: "" },
    { id: 1, number: 2, operation: "", expect: "" },
  ]
})
const formRules = reactive<FormRules>({
  name: [{ required: true, message: '用例名称不能为空', trigger: 'blur' }],
  requestFormId: [{ required: true, message: '提测单不能为空', trigger: 'blur' }],
  functionList: [{ required: true, message: '需求不能为空', trigger: 'blur' }],
  suite: [{ required: true, message: '用例集不能为空', trigger: 'blur' }],
  type: [{ required: true, message: '类型不能为空', trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
const testformList = ref([]) // 提测单列表
const demandList = ref([]) // 需求列表
const testboxList = ref([]) // 用例集列表
const typeList = ref([]) // 测试类型列表
const defaultProps = {
  children: 'children',
  label: 'name',
  value: 'id',
  emitPath: false,
  checkStrictly: true,
}

/** 打开弹窗 */
const open = async (type: string, id?: number, projectid?: any, suiteid?: any) => {
  projectId = projectid.value
  dialogVisible.value = true
  formType.value = type
  dialogTitle.value = t('action.' + type)
  resetForm()
  if (suiteid) {
    formData.value.suite = suiteid.value
  }
  // 修改时，设置数据
  if (id) {
    formLoading.value = true
    try {
      let data = await UseCaseApi.viewUseCase(id)
      formData.value = data
      if (type === 'create') {
        formData.value.logo = ''
        formData.value.id = ''
      }
      formData.value.functionList = JSON.parse(data.functionList)
      formData.value.testCaseStepsDO = data.testCaseStepsDO
    } finally {
      formLoading.value = false
    }
  }
  // 加载提测单列表
  let testform = await UseCaseApi.getTestformList({ projectId: projectId })
  testform.forEach((item) => {
    item.name = item.projectId.name + '-' + item.version.versionName + '(版本)-' + item.rounds + '(轮次)'
  })
  testformList.value = testform
  // 加载用例集列表
  let data = await UseCaseApi.getTestboxTree({ projectId: projectId })
  testboxList.value = [data]
  // 加载测试类型列表
  typeList.value = await UseCaseApi.getTypeList()
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗


const requestFormidChange = async (val) => {
  formData.value.functionList = ''
}

watch(() => formData.value.requestFormId, async (newValue) => {
  if (newValue === '') return
  // 加载需求列表
  demandList.value = await UseCaseApi.getDemandTree({ id: newValue })
})

/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调
const submitForm = async () => {
  // 校验表单
  if (!formRef) return
  const valid = await formRef.value.validate()
  if (!valid) return
  // 提交请求
  formLoading.value = true
  try {
    if (formType.value === 'create') {
      await UseCaseApi.createUseCase({ project: projectId, ...formData.value })
      message.success(t('common.createSuccess'))
    } else {
      await UseCaseApi.updateUseCase({ project: projectId, ...formData.value })
      message.success(t('common.updateSuccess'))
    }
    dialogVisible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}

/** 重置表单 */
const resetForm = () => {
  formData.value = {
    name: '',
    logo: '',
    type: '',
    requestFormId: '',
    functionList: '',
    suite: '',
    review: '',
    initialize: '',
    method: '',
    passCondition: '',
    stopCondition: '',
    testCaseStepsDO: [
      { id: 0, number: 1, operation: "", expect: "" },
      { id: 1, number: 2, operation: "", expect: "" },
    ]
  }
  formRef.value?.resetFields()
}


/** 增加行 */
const handleAdd = (index, row) => {
  let step = { id: 0, number: row.number + 1, operation: "", expect: "" };
  if (formData.value.testCaseStepsDO.length >= 30) {
    message.warning('测试用例步骤不能超过30步，请精简步骤或拆分用例')
    return;
  }
  if (row.number == formData.value.testCaseStepsDO.length) {
    formData.value.testCaseStepsDO.push(step);
  } else {
    let steps_new = [];
    for (let i = 0; i < formData.value.testCaseStepsDO.length; i++) {
      let item = formData.value.testCaseStepsDO[i];
      if (item.number < row.number) {
        steps_new.push(item);
      } else if (item.number == row.number) {
        steps_new.push(item);
        steps_new.push(step);
      } else {
        item.number = item.number + 1;
        steps_new.push(item);
      }
    }
    formData.value.testCaseStepsDO = steps_new;
  }
}
/** 删除行 */
const handleDel = (index, row) => {
  let steps_new = [];
  for (let i = 0; i < formData.value.testCaseStepsDO.length; i++) {
    let item = formData.value.testCaseStepsDO[i];
    if (item.number < row.number) {
      steps_new.push(item);
    } else if (item.number == row.number) {
    } else {
      item.number = item.number - 1;
      steps_new.push(item);
    }
  }
  formData.value.testCaseStepsDO = steps_new;
  if (row.id > 0) {
    // let params = { stepId: row.id };
    // let headers = {
    //   Authorization: JSON.parse(sessionStorage.getItem("token")),
    // };
    // deleteCaseStep(headers, params).then((_data) => {
    //   self.caseList = [];
    //   let { message, code, data } = _data;
    //   if (code === 999999) {
    //     message.success('用例步骤删除成功')
    //   } else {
    //     message.error(message)

    //   }
    // });
  }
  if (formData.value.testCaseStepsDO.length == 0) {
    formData.value.testCaseStepsDO.push({ number: 1, operation: "", expect: "" });
  }
}
/** 上移 */
const handleUp = (index, row) => {
  let steps_new = [];
  for (let i = 0; i < formData.value.testCaseStepsDO.length; i++) {
    let item = formData.value.testCaseStepsDO[i];
    if (item.number < row.number - 1) {
      steps_new.push(item);
    } else if (item.number == row.number - 1) {
      let a = item;
      a.number = a.number + 1;
      let b = formData.value.testCaseStepsDO[i + 1];
      b.number = b.number - 1;
      steps_new.push(b);
      steps_new.push(a);
    } else if (item.number == row.number) {
    } else {
      steps_new.push(item);
    }
  }
  formData.value.testCaseStepsDO = steps_new;
}
/** 下移 */
const handleDown = (index, row) => {
  let steps_new = [];
  for (let i = 0; i < formData.value.testCaseStepsDO.length; i++) {
    let item = formData.value.testCaseStepsDO[i];
    if (item.number < row.number) {
      steps_new.push(item);
    } else if (item.number == row.number) {
      let c = formData.value.testCaseStepsDO[i + 1];
      let a = {
        id: item.id,
        number: item.number + 1,
        operation: item.operation,
        expect: item.expect,
      };
      let b = {
        id: c.id,
        number: c.number - 1,
        operation: c.operation,
        expect: c.expect,
      };
      steps_new.push(b);
      steps_new.push(a);
    } else if (item.number == row.number + 1) {
    } else {
      steps_new.push(item);
    }
  }
  formData.value.testCaseStepsDO = JSON.parse(JSON.stringify(steps_new));
}
</script>


<style>
.formTitle {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 10px;
}
</style>
